/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/

#ifndef PGLWND_H
#define PGLWND_H

#pragma once

#include <pgl/mfc/PGLMouse.h>
#include <pgl/igfx/GDIpInterface.h>
#include <pgl/igfx/GDIpHelper.h>
#include <pgl/mfc/PGLEvent.h>
#include <pgl/mfc/hookwnd.h>

class CPGLWndHooker;

/*! \brief A PGL graph dialog class.


The default behavior of the window is to apply ZoomAll to the region. However, you can disable this feature by
setting the corresponding flag (CPGLWnd::OptionNoZoomAll) in the constructor.

Note that the region pointer is deleted on window destruction.

\ingroup PGLMFCGroup
*/
class PGLMFC_EXT_CLASS CPGLWnd : public CWnd
{
	DECLARE_DYNAMIC(CPGLWnd)

public:
	//! \name Constructors
	//@{
	//! Option flag enumeration
	static enum EOption
	{
		//! No zoom all in OnInitDialog
		OptionNoZoomAll =			0x0001,
		//! Triple buffering (best for animated charts)
		OptionTripleBuffering =		0x0002,
		//! metafile clipboard (default is bitmap)
		OptionClipboardMetafile =	0x0004
	};
	//! Default constructor
	CPGLWnd(CPGLRegionPtr pRegion = CPGLRegionPtr(), DWORD dwFlags = 0);
	virtual ~CPGLWnd();
	//@}

	//! \name Interface and GDI+ helper
	//@{
	//! return reference to gfx interface
	gfxinterface::CGDIpInterface& GetGfxInterface()				{	return m_GDIpInterface;};
	//! return reference to gfx interface, const
	const gfxinterface::CGDIpInterface& GetGfxInterface() const	{	return m_GDIpInterface;};
	//! returns reference to GDI+ helper
	pgl::CGDIpHelperRegion& GetGDIpHelper()			{	return m_GDIpHelper;};
	//! returns reference to GDI+ helper, const
	const pgl::CGDIpHelperRegion& GetGDIpHelper() const{	return m_GDIpHelper;};
	//@}

	//! \name Region
	//@{
	//! return graph pointer
	CPGLRegionPtr GetRegion()				{	return m_pRegion;};
	//! Set graphGL.
	void SetRegion(CPGLRegionPtr _region)	{	m_pRegion=_region; m_GDIpHelper.SetRegion(_region);};
	//! Destroy region
	void DestroyRegion()					{	m_pRegion.reset();};
	//@}

	//! \name Event
	//@{
	void SetEvent( CPGLEventPtr pEvent);
	CPGLEventPtr GetEvent()								{	return m_pEvent;};
	const CPGLEventPtr GetEvent()	const				{	return m_pEvent;};
	void ClearEvent();
	//@}

	//! \name Resizing state
	//@{
	//! Sets the window size
	void SetSize(int cx, int cy);
	//! The view has been resized, and the charts have to be refreshed
	void PostResize()					{	m_bPostResize = true;};
	//! return true if refreshing is needed (used internally)
	bool IsResizeNeeded()				{	return m_bPostResize;};
	//! reset resize bit
	void ResetResizeState()				{	m_bPostResize = false;};
	//@}

	//! \name Redrawing
	//@{
	//! enables disables triple buffering
	void SetTripleBuffering(bool on = true);
	//! Makes rebuilding memory bitmap and redrawing the chart
	void SetDirty();
	//! Makes rebuilding memory bitmap and redrawing the chart
	void SetFrontDirty();
	//! Makes blitting of memory bitmap
	void SetCacheDirty();
	//@}

protected:
    friend class CPGLWndHooker;

	// Generated message map functions
	//{{AFX_MSG(CPGLWnd)
	afx_msg void OnPaint();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg BOOL OnEraseBkgnd( CDC* pDC );
	afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );
	afx_msg void OnDestroy( );
	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()


	CPGLMouse m_mouse;
	CPGLRegionPtr m_pRegion;
	UINT m_uPointedRegion;
	CPGLEventPtr m_pEvent;
	DWORD m_dwFlags;

	CPGLArchive::EClipBoardType m_eClipboardType;
	gfxinterface::CGDIpInterface m_GDIpInterface;
	pgl::CGDIpHelperRegion m_GDIpHelper;

	bool m_bPostResize;
};

/*! \brief Help class for hooking CPGLWnd

*/
class PGLMFC_EXT_CLASS CPGLWndHooker : public CHookWnd
{
public:
    virtual LRESULT WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam);
};

#endif
